package security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;


import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.AntUrlPathMatcher;
import org.springframework.security.web.util.UrlMatcher;

import service.interf.IResource;


public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	private IResource iResource;
	private static Map<String, Collection<ConfigAttribute> > resourceMap = new HashMap<String, Collection<ConfigAttribute>>(0);
	private UrlMatcher urlMatcher = new AntUrlPathMatcher();;
	
	
	public static Map<String, Collection<ConfigAttribute>> getResourceMap() {
		return resourceMap;
	}

	public static void setResourceMap(
			Map<String, Collection<ConfigAttribute>> resourceMap) {
		MyInvocationSecurityMetadataSource.resourceMap = resourceMap;
	}

	public IResource getiResource() {
		return iResource;
	}

	public void setiResource(IResource iResource) {
		this.iResource = iResource;
	}

	public MyInvocationSecurityMetadataSource(IResource iResource) throws Exception {
		setiResource(iResource);
		loadResource();
	}
	
	public void loadResource() throws Exception {
		if(!resourceMap.isEmpty()) { return; }
		Map map = iResource.findAllResourcesWithAuth();
		for(Iterator it = map.entrySet().iterator(); it.hasNext();) {
			Collection<ConfigAttribute> attris = new ArrayList<ConfigAttribute>(0);
			Entry et = (Entry)it.next();
			ArrayList<String> auths =(ArrayList) et.getValue();
			for(String auth : auths) {
				ConfigAttribute cfa = new SecurityConfig(auth);
				attris.add(cfa);
			}
			resourceMap.put((String) et.getKey(), attris);
		}
	}
	
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		String url = ((FilterInvocation) object).getRequestUrl();
		if(!resourceMap.isEmpty()){
			Iterator<String> it = resourceMap.keySet().iterator();
			while (it.hasNext()) {
				String resURL = it.next();
				if (urlMatcher.pathMatchesUrl(url, resURL)) {
					return resourceMap.get(resURL);
				}
			}
		}
		return null;
	}

	/**
	 * 更改权限
	 * url对应多个权限
	 * url在map中，同时没有权限数组，删除url对应的权限
	 */
	public synchronized static void changeAuthority(String url, ArrayList<String> v){
		Collection<ConfigAttribute> attris = new ArrayList<ConfigAttribute>();
		for(String au : v){
			ConfigAttribute ca = new SecurityConfig(au);
			attris.add(ca);
		}
		if(0 == v.size()) {
			resourceMap.remove(url);
		} else {
			resourceMap.put(url, attris);
		}
	}
	
	
	public boolean supports(Class<?> arg0) {
		// TODO Auto-generated method stub
		return true;
	}
	
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		// TODO Auto-generated method stub
		return null;
	}

}
